﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace LibGreen.Oscar.ObjectManagers.SSI
{
	internal class Icon : IServerSideItem
	{
		public byte[] Hash;
		public ushort ID = 0;

		public uint IconSize = 0;
		public ushort Checksum = 0;
		public uint Stamp = 0;

		/// <summary>
		/// Computes checksums and hashes for a buddy icon
		/// </summary>
		/// <param name="filename">The filename of the icon</param>
		/// <returns><c>true</c> if the server-side icon should be updated, <c>false</c> otherwise</returns>
		public bool ComputeItems (string filename)
		{
			bool retval = false;
			if (String.IsNullOrEmpty (filename))
				return retval;

			try {
				byte[] hash = null;
				FileStream fs = File.OpenRead (filename);
				DateTime epoch = new DateTime (1970, 1, 1, 0, 0, 0);

				this.Stamp = (uint)(File.GetLastWriteTime (filename) - epoch).TotalSeconds;
				this.IconSize = (uint)fs.Length;
				this.Checksum = ChecksumIcon (filename);

				hash = System.Security.Cryptography.MD5.Create ().ComputeHash (fs);
				if (this.Hash == null) {
					this.Hash = hash;
				}

				for (int i = 0; i < this.Hash.Length; i++) {
					if (this.Hash[i] != hash[i])
						retval = true;
				}
			}
			catch {
				retval = false;
			}

			return retval;
		}

		private ushort ChecksumIcon (string filename)
		{
			uint retval = 0;
			int i = 0;

			using (StreamReader sr = new StreamReader (filename)) {
				byte[] buffer = new byte[sr.BaseStream.Length];
				sr.BaseStream.Read (buffer, 0, buffer.Length);

				for (i = 0; i + 1 < buffer.Length; i += 2) {
					retval += (uint)((buffer[i + 1] << 8) + buffer[i]);
				}

				if (i < buffer.Length)
					retval += buffer[i];

				retval = ((retval & 0xffff0000) >> 16) + (retval & 0x0000ffff);
			}
			return (ushort)retval;
		}

		#region IServerSideItem Members

		public ushort ItemID
		{
			get { return ID; }
		}

		#endregion

		#region IComparable Members

		public int CompareTo (object obj)
		{
			if (obj is Icon) {
				return this.ID.CompareTo ((obj as Icon).ID);
			}
			return -1;
		}

		#endregion
	}
}
